package cn.zs.supply.common.core.security.simple;

import cn.zs.supply.common.constants.enums.MsgDataEnum;
import cn.zs.supply.common.constants.enums.PubErrCode;
import cn.zs.supply.common.core.login.LoginContext;
import cn.zs.supply.common.core.login.domain.LoginInfo;
import cn.zs.supply.common.utils.ResponseUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.security.jwt.crypto.sign.RsaVerifier;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
 * 拦截请求进行token验证
 */
@Component
public class JwtHeadFilter extends OncePerRequestFilter {
    private RsaVerifier verifier;
    @Value("${application.type}")
    private String LongType;
    @Autowired
    private RedisTemplate<String, Object> redisTemplat;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = request.getHeader("Authentication");
        if (token==null || token.isEmpty()){
            filterChain.doFilter(request,response);
            return;
        }
        JwtUser user;
        try {
            Jwt jwt = JwtHelper.decodeAndVerify(token, verifier);
            String claims = jwt.getClaims();
            user = JSON.parseObject(claims, JwtUser.class);
            Object nameToken=redisTemplat.opsForValue().get(LongType+user.getUsername());
            if(nameToken==null){
                JSONObject responseJson=new JSONObject();
                responseJson.put("code", PubErrCode.SIGN_MISMATCHING.getCode());
                responseJson.put("errcode",PubErrCode.SIGN_MISMATCHING.getCode());
                responseJson.put("msg",PubErrCode.SIGN_MISMATCHING.getMsg());
                responseJson.put("success", "true");
                ResponseUtil.setResponse(response,responseJson);
                return;
            }
            Object loginInfoObj =  redisTemplat.opsForValue().get(token);
            LoginContext.get().setObject(loginInfoObj);
            System.setProperty(MsgDataEnum.FEIGN_TOKEN.getCode(), token);
        }catch (Exception e){
            JSONObject responseJson=new JSONObject();
            responseJson.put("code", PubErrCode.SIGN_MISMATCHING.getCode());
            responseJson.put("errcode",PubErrCode.SIGN_MISMATCHING.getCode());
            responseJson.put("msg",PubErrCode.SIGN_MISMATCHING.getMsg());
            responseJson.put("success", "true");
            ResponseUtil.setResponse(response,responseJson);
            return;
        }
        JwtLoginToken jwtLoginToken = new JwtLoginToken(user, "", user.getAuthorities());
        jwtLoginToken.setDetails(new WebAuthenticationDetails(request));
        SecurityContextHolder.getContext().setAuthentication(jwtLoginToken);
        filterChain.doFilter(request,response);
    }
    public void setVerifier(RsaVerifier verifier) {
        this.verifier = verifier;
    }
}
